import express from 'express';
import { body, validationResult, query, param } from 'express-validator';
import { Question, Expert, Domain, UserQuota } from '../../models/index.js';
import { authenticateMobileUser } from '../../middleware/auth.js';
import { questionLimiter } from '../../middleware/rateLimiter.js';
import { catchAsync, BusinessError, NotFoundError } from '../../middleware/errorHandler.js';
import { getAIAnswer } from '../../utils/ai.js';
import { success, paginated } from '../../utils/response.js';

const router = express.Router();

// 用户提交问题
router.post('/ask',
  authenticateMobileUser,
  questionLimiter,
  [
    body('expert_id')
      .isInt({ min: 1 })
      .withMessage('专家ID必须是正整数'),
    body('question')
      .notEmpty()
      .withMessage('问题不能为空')
      .isLength({ max: 2000 })
      .withMessage('问题不能超过2000个字符'),
    body('preconditions')
      .optional()
      .custom((value) => {
        if (value === null || value === undefined) return true;
        if (typeof value === 'object' && !Array.isArray(value)) return true;
        throw new Error('前置条件必须是对象');
      })
  ],
  catchAsync(async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      throw new BusinessError('参数验证失败', errors.array());
    }

    const { expert_id, question, preconditions = {} } = req.body;
    const userId = req.user.id;
    
    // 查找专家和领域信息
    const expert = await Expert.findByIdWithDomain(expert_id);
    if (!expert || !expert.is_enabled) {
      throw new NotFoundError('专家不存在或已禁用');
    }
    
    const domain = expert.domain;
    if (!domain || !domain.is_enabled) {
      throw new BusinessError('专家所属领域已禁用');
    }
    
    // 查找可用的额度
    let quota = null;
    
    // 1. 优先使用专家定向额度
    quota = await UserQuota.findAvailableQuota(userId, 'expert', expert_id);
    
    // 2. 其次使用领域额度
    if (!quota) {
      quota = await UserQuota.findAvailableQuota(userId, 'domain', domain.id);
    }
    
    // 3. 最后使用通用额度
    if (!quota) {
      quota = await UserQuota.findAvailableQuota(userId, 'general');
    }
    
    if (!quota || !quota.canUse()) {
      throw new BusinessError('额度不足，请先购买提问次数');
    }
    
    // 创建问答记录
    const questionRecord = await Question.createQuestion({
      user_id: userId,
      expert_id: expert_id,
      question,
      preconditions,
      user_quota_id: quota.id,
      status: 'pending'
    });
    
    try {
      // 扣减额度
      await quota.useQuota();
      
      // 调用AI获取答案
      const aiResult = await getAIAnswer(question, expert, domain, preconditions);
      
      // 更新问答记录
      await questionRecord.setAnswer(aiResult.answer, aiResult.requestId);
      
      // 重新查询完整的问答记录
      const completeQuestion = await Question.findByPk(questionRecord.id, {
        include: [
          { 
            association: 'expert', 
            attributes: ['id', 'nickname', 'avatar_url'],
            include: [{ 
              association: 'domain', 
              attributes: ['id', 'name'] 
            }]
          }
        ]
      });
      
      res.json(success({
        question: completeQuestion
      }, '问题提交成功'));
    } catch (error) {
      // AI调用失败，记录错误并回滚额度
      await questionRecord.setFailed(error.message);
      
      // 回滚额度（增加已使用次数的相反操作）
      quota.used_count -= 1;
      quota.remaining_count = quota.total_count - quota.used_count;
      await quota.save();
      
      throw new BusinessError('AI服务暂时不可用，请稍后重试');
    }
  })
);

// 获取用户的问答历史 (不带参数的路由，必须放在带参数路由前面)
router.get('/my-questions',
  authenticateMobileUser,
  [
    query('page').optional().isInt({ min: 1 }).withMessage('页码必须是正整数'),
    query('limit').optional().isInt({ min: 1, max: 50 }).withMessage('每页数量必须在1-50之间'),
    query('expert_id').optional().isInt({ min: 1 }).withMessage('专家ID必须是正整数'),
    query('status').optional().isIn(['pending', 'answered', 'failed']).withMessage('状态参数无效')
  ],
  catchAsync(async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      throw new BusinessError('参数验证失败', errors.array());
    }

    const { page = 1, limit = 20, expert_id, status } = req.query;
    const userId = req.user.id;

    const result = await Question.getUserQuestions(userId, {
      page: parseInt(page),
      limit: parseInt(limit),
      expertId: expert_id ? parseInt(expert_id) : undefined,
      status
    });

    res.json(paginated(result.rows, {
      page: parseInt(page),
      limit: parseInt(limit),
      total: result.count,
      pages: Math.ceil(result.count / parseInt(limit))
    }, '获取用户问答记录成功'));
  })
);

// 用户对答案评分 (带参数的路由)
router.post('/:id/rating',
  authenticateMobileUser,
  [
    param('id').isInt({ min: 1 }).withMessage('问题ID必须是正整数'),
    body('rating')
      .isIn(['unsatisfied', 'normal', 'satisfied'])
      .withMessage('评分必须是unsatisfied、normal或satisfied')
  ],
  catchAsync(async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      throw new BusinessError('参数验证失败', errors.array());
    }

    const { id } = req.params;
    const { rating } = req.body;
    const userId = req.user.id;

    const question = await Question.findByPk(id);
    if (!question) {
      throw new NotFoundError('问题不存在');
    }

    if (question.user_id !== userId) {
      throw new BusinessError('只能对自己的问题进行评分');
    }

    if (question.status !== 'answered') {
      throw new BusinessError('只能对已回答的问题进行评分');
    }

    if (question.rating) {
      throw new BusinessError('该问题已经评分过了');
    }

    await question.setRating(rating);

    // 重新查询完整的问题信息，包含关联数据
    const completeQuestion = await Question.findByPk(question.id, {
      include: [
        {
          association: 'expert',
          attributes: ['id', 'nickname', 'avatar_url'],
          include: [{
            association: 'domain',
            attributes: ['id', 'name']
          }]
        },
        { association: 'quota', attributes: ['id', 'quota_type'] }
      ]
    });

    res.json(success({
      question: completeQuestion
    }, '评分成功'));
  })
);

// 获取问题详情 (带参数的路由，必须放在最后)
router.get('/:id',
  authenticateMobileUser,
  [
    param('id').isInt({ min: 1 }).withMessage('问题ID必须是正整数')
  ],
  catchAsync(async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      throw new BusinessError('参数验证失败', errors.array());
    }

    const { id } = req.params;
    const userId = req.user.id;

    const question = await Question.findByPk(id, {
      include: [
        {
          association: 'expert',
          attributes: ['id', 'nickname', 'avatar_url', 'bio'],
          include: [{
            association: 'domain',
            attributes: ['id', 'name']
          }]
        },
        { association: 'quota', attributes: ['id', 'quota_type'] }
      ]
    });

    if (!question) {
      throw new NotFoundError('问题不存在');
    }

    if (question.user_id !== userId) {
      throw new BusinessError('只能查看自己的问题');
    }

    res.json(success({
      question
    }, '获取问题详情成功'));
  })
);

export default router;
